package com.ruoyi.ncpcs.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.ncpcs.domain.BaseReq;
import com.ruoyi.ncpcs.domain.DataQueryReq;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author daotian
 */
@Component
public class InterfaceUtils {

    private static String interfaceUrl;

    private static String appId;

    private static String appSecret;

    @Value("${ncpcs.interface_url}")
    public  void setInterfaceUrl(String interfaceUrl) {
        InterfaceUtils.interfaceUrl = interfaceUrl;
    }
    @Value("${ncpcs.appId}")
    public  void setAppId(String appId) {
        InterfaceUtils.appId = appId;
    }
    @Value("${ncpcs.appSecret}")
    public  void setAppSecret(String appSecret) {
        InterfaceUtils.appSecret = appSecret;
    }

    public static String genNcSign(BaseReq req) {
        String params =
                "ncAppid=" + req.getNcAppid() + "&ncMethod=" + req.getNcMethod() + "&ncTimestamp=" + req.getNcTimestamp() + "&ncVersion=" + req.getNcVersion() + "&ncHistory=" + req.getNcHistory() + "&ncCancel=" + req.getNcCancel() + "&ncNonce=" + req.getNcNonce() + "&ncBranchID=" + req.getNcBranchID() + "&appSecret=" + req.getAppSecret();
        params = params.toLowerCase();
        String sign1 = DigestUtils.md5DigestAsHex(params.getBytes());
        System.out.println(sign1);
        byte[] digest = DigestUtils.md5Digest(params.getBytes());
        String sign = parseByte2HexStr(digest);
        return sign;
    }

    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toLowerCase());
        }
        return sb.toString();
    }

    public static String getRandom() {
        return System.currentTimeMillis() + "" + new Random().nextInt(10);
    }

    public static String getTime(){
        LocalDateTime localDateTime = LocalDateTime.now();
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
    }

    public static Map<String,Set> uploadData(BaseReq req){
        //转成Form表单格式上传
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap(){
            {
                add("ncAppid", req.getNcAppid());
                add("ncMethod", req.getNcMethod());
                add("ncTimestamp", req.getNcTimestamp());
                add("ncVersion", req.getNcVersion());
                add("ncHistory", req.getNcHistory());
                add("ncCancel", req.getNcCancel());
                add("ncNonce", req.getNcNonce());
                add("ncBranchID", req.getNcBranchID());
                add("ncSign",InterfaceUtils.genNcSign(req));
                add("ncData",req.getNcData());
            }
        };
        // 3.创建RestTemplate
        RestTemplate restTemplate = new RestTemplate();
        // 4.设置RestTemplate参数(请求头和body)
        HttpHeaders headers = new HttpHeaders();
        MediaType mediaType = MediaType.parseMediaType("application/x-www-form-urlencoded; charset=UTF-8");
        headers.setContentType(mediaType);
        headers.add("Accept", "application/json");
        HttpEntity< MultiValueMap<String, Object>> entity = new HttpEntity<>(paramMap, headers);
        // 5.使用RestTemplate发起请求与接收返回值
        String resultData = restTemplate.postForObject(interfaceUrl, entity, String.class);
        Map<String,Set> uploadResult = analysisResultData(resultData);
        Set<Map<String,String>> set = new HashSet<>();
        Map resultDataMap = new HashMap();
        resultDataMap.put("resultData",resultData);
        set.add(resultDataMap);
        uploadResult.put("resultData", set);
        return uploadResult;
    }

    public static void buildInterfaceReq(DataQueryReq queryReq, BaseReq req) {
        req.setNcAppid(appId);
        req.setAppSecret(appSecret);
        req.setNcMethod(queryReq.getNcMethod());
        req.setNcTimestamp(InterfaceUtils.getTime());
        req.setNcVersion(queryReq.getNcVersion());
        req.setNcHistory(queryReq.getNcHistory());
        req.setNcCancel(queryReq.getNcCancel());
        req.setNcNonce(InterfaceUtils.getRandom());
        req.setNcBranchID(queryReq.getNcBranchID());
    }

    public static Map<String,Set> analysisResultData(String resultData){
        Map<String,Set> resultMap = new HashMap<>();
        JSONObject resultDataJson = JSONObject.parseObject(resultData);
        JSONObject resultDataMsgJson = resultDataJson.getJSONObject("msg");
        JSONArray ncErrorDataJsonArray = resultDataMsgJson.getJSONArray("ncErrorDataList");
        Set<Map<String,String>> allDataSet = new HashSet<>();
        Set<Map<String,String>> successDataSet = new HashSet<>();
        Set<Map<String,String>> failDataSet = new HashSet<>();
        for(int i=0;i<ncErrorDataJsonArray.size();i++){
            JSONObject ncErrorDataJson = ncErrorDataJsonArray.getJSONObject(i);
            if(ncErrorDataJson.getString("ncErrLevel").equals("1-致命")||ncErrorDataJson.getString("ncErrLevel").equals("2-严重")){
                Map<String,String> map = new HashMap<>();
                map.put(ncErrorDataJson.getString("ncMedicalRecordNo"),ncErrorDataJson.getString("ncDischargeTime"));
                failDataSet.add(map);
            }
            Map<String,String> map1 = new HashMap<>();
            map1.put(ncErrorDataJson.getString("ncMedicalRecordNo"),ncErrorDataJson.getString("ncDischargeTime"));
            allDataSet.add(map1);
        }
        for(Map<String,String> map : allDataSet){
            if(!failDataSet.contains(map)){
                successDataSet.add(map);
            }
        }
        resultMap.put("success",successDataSet);
        resultMap.put("fail",failDataSet);
        return resultMap;
    }
}
